#include <sys/types.h>
#include <sys/socket.h>
#include <string>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include "log.hpp"

log l(1);

class udpserver
{
public:
    udpserver(uint16_t port, const std::string& ip = "0")
    : _port(htons(port))
    {}

    void init()
    {
        //1.创建套接字
        _sockfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_sockfd == -1)
        {
            l(Error, __LINE__, "udpserver->init: socket error");
            exit(-1);
        }
        l(Info, __LINE__, "socket create success");

        //2.绑定端口
        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = _port;
        //local.sin_addr.s_addr = inet_addr(_ip.c_str()); //将字符串转为 in_addr_t
        local.sin_addr.s_addr = htonl(INADDR_ANY); //全0，默认只要是发到这个主机的都要根据端口号向上交付
        if (bind(_sockfd, reinterpret_cast<struct sockaddr*>(&local), sizeof(local)) < 0)
        {
            l(Error, __LINE__, "udpserver->init: bind error");
            exit(-1);
        }
        l(Info, __LINE__, "bind success");
    }

    void Run()
    {
        char inbuf[1024];
        struct sockaddr_in client;
        socklen_t size = sizeof(client);
        while (true)
        {
            bzero(&client, sizeof(client));
            ssize_t n = recvfrom(_sockfd, inbuf, 1023, 0, reinterpret_cast<struct sockaddr*>(&client), &size);
            if (n < 0)
            {
                l(Warning, __LINE__, "udpserver->Run: recvfrom error");
                continue;
            }

            inbuf[n] = '\0';
            std::string s(inbuf);
            std::cout << "client: " << s << std::endl;
            s += "  -> xxhhdzl recever success!!!"; 
            n = sendto(_sockfd, s.c_str(), s.size(), 0, reinterpret_cast<struct sockaddr*>(&client), sizeof(client));
            if (n < 0)
            {
                l(Warning, __LINE__, "udpserver->Run: sendto error");
                continue;
            }
        }
    }

    ~udpserver()
    {

    }
private:

    struct Ip
    {
        uint8_t part1;
        uint8_t part2;
        uint8_t part3;
        uint8_t part4;
    };

    std::string To_string(uint32_t ip)
    {
        
        struct Ip* IP = reinterpret_cast<struct Ip*>(ntohl(ip));
        return std::to_string(IP->part1) + "." + std::to_string(IP->part1) + "." + std::to_string(IP->part1) + "." + std::to_string(IP->part1);
    }

    // int Stoi(const std::string& ip)
    // {
        
    // }
private:
    int _sockfd; //网络文件描述符
    uint16_t _port; //服务器进程端口号
    std::string _ip;
};